package com.ruoyi.socket.service.impl;

import cn.hutool.http.HttpRequest;
import com.ruoyi.bussiness.domain.TContractCoin;
import com.ruoyi.bussiness.domain.TCurrencySymbol;
import com.ruoyi.bussiness.domain.TSecondCoinConfig;
import com.ruoyi.bussiness.service.ITContractCoinService;
import com.ruoyi.bussiness.service.ITCurrencySymbolService;
import com.ruoyi.bussiness.service.ITSecondCoinConfigService;
import com.ruoyi.bussiness.service.ITSymbolManageService;
import com.ruoyi.common.core.domain.entity.SysDictData;
import com.ruoyi.common.service.FinancialDataService;
import com.ruoyi.common.utils.AllTickApiUtil;
import com.ruoyi.socket.manager.WebSocketUserManager;
import com.ruoyi.system.service.ISysDictTypeService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.net.URISyntaxException;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.util.*;


@Slf4j
@Component
public class MarketThreadMt5 {


    @Resource
    private ITSecondCoinConfigService secondCoinConfigService;
    @Resource
    private ITContractCoinService contractCoinService;
    @Resource
    private ITCurrencySymbolService tCurrencySymbolService;
    @Resource
    private ITSymbolManageService tSymbolManageService;

    @Resource
    private WebSocketUserManager webSocketUserManager;
    @Resource
    private ISysDictTypeService sysDictTypeService;
    @Resource
    private FinancialDataService financialDataService;
    @Async
    @Scheduled(cron = "*/15 * * * * ?")
    public void marketThreadRun() throws URISyntaxException {
        LocalDate today = LocalDate.now();
        DayOfWeek dayOfWeek = today.getDayOfWeek();
        Set<String> strings = new HashSet<>();
        //秒合约
        TSecondCoinConfig tSecondCoinConfig = new TSecondCoinConfig();
        tSecondCoinConfig.setMarket("mt5");
        tSecondCoinConfig.setStatus(1L);
        List<TSecondCoinConfig> tSecondCoinConfigs = secondCoinConfigService.selectTSecondCoinConfigList(tSecondCoinConfig);
        for (TSecondCoinConfig secondCoinConfig : tSecondCoinConfigs) {
            strings.add(secondCoinConfig.getSymbol().toUpperCase());
        }
        //U本位
        TContractCoin tContractCoin =new TContractCoin();
        tContractCoin.setEnable(0L);
        tContractCoin.setMarket("mt5");
        List<TContractCoin> tContractCoins = contractCoinService.selectTContractCoinList(tContractCoin);
        for (TContractCoin contractCoin : tContractCoins) {
            strings.add(contractCoin.getSymbol().toUpperCase());
        }
        //币币
        TCurrencySymbol tCurrencySymbol = new TCurrencySymbol();
        tCurrencySymbol.setEnable("1");
        tCurrencySymbol.setMarket("mt5");
        List<TCurrencySymbol> tCurrencySymbols = tCurrencySymbolService.selectTCurrencySymbolList(tCurrencySymbol);
        for (TCurrencySymbol currencySymbol : tCurrencySymbols) {
            strings.add(currencySymbol.getSymbol().toUpperCase());
        }

        //字典银行卡绑定币种
        List<SysDictData> backCoinList = sysDictTypeService.selectDictDataByType("t_bank_coin");
        if (!CollectionUtils.isEmpty(backCoinList)){
            for (SysDictData sysDictData : backCoinList) {
                if ("USD".equalsIgnoreCase(sysDictData.getDictValue())) continue;
                strings.add(sysDictData.getDictValue().toUpperCase()+"USD");
                strings.add("USD"+sysDictData.getDictValue().toUpperCase());
            }
        }
        // 使用统一的金融数据服务获取所有外汇数据
        Map<String, String> forexDataMap = financialDataService.getForexData();
        
        //兑换
        for (String string : strings) {

            Thread thread = new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        // 从统一服务获取数据
                        String result = forexDataMap.get(string.toUpperCase());
                        
                        if (result != null && !result.isEmpty() && !result.equals("{}")) {
                            log.debug("外汇数据获取成功: {} -> {}", string, result.length() > 100 ? result.substring(0, 100) + "..." : result);
                            
                            webSocketUserManager.mt5KlineSendMeg(result, string);
                            webSocketUserManager.mt5DETAILSendMeg(result, string);
                        } else {
                            log.warn("外汇数据为空，使用模拟数据: {}", string);
                            // 备用方案：使用模拟数据
                            String mockResult = generateMockForexData(string);
                            webSocketUserManager.mt5KlineSendMeg(mockResult, string);
                            webSocketUserManager.mt5DETAILSendMeg(mockResult, string);
                        }
                        
                    } catch (Exception e) {
                        log.error("外汇数据处理失败: {}, 错误: {}", string, e.getMessage());
                        // 备用方案：使用模拟数据
                        String mockResult = generateMockForexData(string);
                        webSocketUserManager.mt5KlineSendMeg(mockResult, string);
                        webSocketUserManager.mt5DETAILSendMeg(mockResult, string);
                    }
                }
            });
            thread.start();
        }
    }
    
    /**
     * 生成模拟外汇数据（备用方案）
     */
    private String generateMockForexData(String symbol) {
        double basePrice = getBaseForexPrice(symbol);
        double randomChange = (Math.random() - 0.5) * 0.02; // ±1%随机变化
        double currentPrice = basePrice * (1 + randomChange);
        
        // 使用AllTickApiUtil生成标准的fx678格式数据
        return AllTickApiUtil.createFx678ArrayFormat(symbol, 0, 0, 0, 0, currentPrice);
    }
    
    /**
     * 获取基础外汇价格
     */
    private double getBaseForexPrice(String symbol) {
        switch (symbol.toUpperCase()) {
            case "EURUSD": return 1.0500;
            case "GBPUSD": return 1.2500;
            case "USDJPY": return 150.00;
            case "USDCHF": return 0.9000;
            case "AUDUSD": return 0.6500;
            case "NZDUSD": return 0.6000;
            case "USDCAD": return 1.3500;
            case "EURGBP": return 0.8500;
            case "EURJPY": return 157.50;
            case "GBPJPY": return 187.50;
            case "AUDJPY": return 97.50;
            case "NZDJPY": return 90.00;
            case "CHFJPY": return 166.67;
            case "CADJPY": return 111.11;
            default: return 1.0000;
        }
    }
}
